package com.yeyks.rocketmq.service.customer;

import cn.hutool.json.JSONUtil;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yeyks.common.constants.MessageTemplate;
import com.yeyks.common.constants.OrderStatus;
import com.yeyks.common.dto.mq.OrderCheckToWebMessage;
import com.yeyks.common.utils.DateUtils;
import com.yeyks.commonReference.service.consumer.MessageNoticeTemplateService;
import com.yeyks.commonReference.service.consumer.UserCouponInfoService;
import com.yeyks.commonReference.service.hotel.HotelInfoService;
import com.yeyks.commonReference.service.order.OrderHeadService;
import com.yeyks.consumer.dal.domain.UserCouponInfo;
import com.yeyks.consumer.service.MessageNoticeService;
import com.yeyks.hotel.dal.domain.HotelInfo;
import com.yeyks.order.dal.domain.OrderHead;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * @author fuchangshuai
 * @date 2019/08/09 16:06
 */
@Slf4j
@Component
public class OrderDelayCheckListener implements MessageListener {
    @Autowired
    private OrderHeadService orderHeadService;
    @Autowired
    private UserCouponInfoService userCouponInfoService;
    @Autowired
    private HotelInfoService hotelInfoService;
    @Autowired
    private MessageNoticeService noticeService;
    @Autowired
    private MessageNoticeTemplateService templateService;

    @Override
    public Action consume(Message message, ConsumeContext consumeContext) {
        try {
            Long startTime = System.currentTimeMillis();
            byte[] body = message.getBody();
            //获取到接收的消息，由于接收到的是byte数组，所以需要转换成字符串
            String msg = new String(body);
            //处理业务逻辑
            disposeLogic(msg);
            log.info("下单30分钟检测：监听到的消息：message = {}", msg);
            Long endTime = System.currentTimeMillis();
            log.info("下单30分钟检测：单次消费耗时：" + (endTime - startTime) / 1000);
        } catch (Exception e) {
            log.error("MessageListener.consume error:" + e.getMessage(), e);
        }
        return Action.CommitMessage;
    }

    /**
     * 3.4手动自动抢单，处理业务逻辑
     *
     * @param msg 监听到的信息
     */
    private void disposeLogic(String msg) {
        try {
            OrderCheckToWebMessage message = JSONUtil.toBean(msg, OrderCheckToWebMessage.class);
            if (null == message) {
                return;
            }
            OrderHead orderHead = orderHeadService.getOne(new QueryWrapper<OrderHead>()
                    .eq(OrderHead.ORDER_NO, message.getOrderNo())
                    .eq(OrderHead.STATUS, OrderStatus.prePay).last("limit 1"));
            if (null != orderHead) {
                orderHead.setStatus(OrderStatus.cancle);
                orderHead.setGmtModified(new Date());
                if (orderHeadService.updateById(orderHead)) {
                    //修改房态信息
                    updateRoomCount(orderHead);
                    //如果券存在修改券的使用状态
                    if (null != orderHead.getUserCouponId()) {
                        userCouponInfoService.update(new UpdateWrapper<UserCouponInfo>()
                                .set(UserCouponInfo.USED, 0)
                                .eq(UserCouponInfo.ID, orderHead.getUserCouponId()));
                    }
                    //订单取消通知
                    messageNotice(orderHead);
                } else {
                    log.info("修改订单状态为已取消失败:orderNo = {}", orderHead.getOrderNo());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("下单30分钟检测：处理监听消息异常：msg = {}", msg);
        }
    }

    /**
     * 修改房态信息
     *
     * @param orderHead
     */
    private void updateRoomCount(OrderHead orderHead) {
        try {
            if (null == orderHead.getVipFlag()) {
                return;
            }
            orderHeadService.setRoomCount(orderHead.getOrderNo(), orderHead.getVipFlag(), 0);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("更新房态信息失败orderNo = {}", orderHead.getOrderNo());
        }
    }

    /**
     * 写入消息
     *
     * @param orderHead
     */
    private void messageNotice(OrderHead orderHead) {
        try {
            HotelInfo hotelInfo = hotelInfoService.getById(orderHead.getHotelId());
            if (hotelInfo == null) {
                return;
            }
            String checkIn = DateUtils.toYYMMddStr(orderHead.getCheckIn());
            String checkOut = DateUtils.toYYMMddStr(orderHead.getCheckOut());
            Map<String, String> map = templateService.orderAfterHandleValue(MessageTemplate.ORDER_CANCLE, hotelInfo.getName(), checkIn, checkOut, orderHead.getDays());
            noticeService.createNoticeAndSave(map, orderHead.getUserId(), orderHead.getHotelId());
        } catch (Exception e) {
            log.error("30分钟订单取消异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }
}
